﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using YellowMap.Resources;
using System.Diagnostics;
using System.Windows.Documents;
using Microsoft.Phone.Maps.Controls;
using System.Threading.Tasks;
using System.Device.Location;
using YellowMap.View.Control;
using YellowMap.View.Page;
using System.Windows.Threading;
using System.Windows.Media;
using System.Windows.Input;
using Microsoft.Phone.Tasks;

namespace YellowMap
{

    public enum MainPage_Command
    {
        NONE,

        SEARCH_NEAR_BY,
        SEARCH_NORMAL,
        SEARCH_HISTORY,
        SEARCH_FAVORITE,
        SEARCH_BYKEYWORD,
        SHOW_HISTORY,
        SHOW_FAVORITE,

        GET_DIRECTION,
        MOVE_MAP

    }

    public partial class MainPage : PhoneApplicationPage
    {
        public static bool isWaitingShow = false;
        public static bool isGPSDisable = false;
        public static float move_map_lat = 0;
        public static float move_map_lng = 0;
        public bool ischangelanguage;
        public string LanguageChange = AppViewModel.Instance.SettingVM.Language;
        public DirectionMap directionMap { get; set; }
        public GoogleDirectionResponse DirectionResponse { get; set; }
        public static MainPage_Command COMMAND { get; set; }
        public static Favorite SelectedFavorite { get; set; }
        public static History SelectedHistory { get; set; }
        public static string SearchKeyword { get; set; }
        public static bool isfrist = true;
        public static MainPage Instance { get; set; }
        MapLayer layerPushPin = new MapLayer();
        MapPolyline polylineDirection = new MapPolyline();
        // Constructor
        public MainPage()
        {
            timerInternetTimeOut.Tick += timerInternetTimeOut_Tick;
            InitializeComponent();
            Instance = this;
            
            ReloadLanguage(AppViewModel.Instance.SettingVM.Language);
            LoadState();
            bingMap.Layers.Add(layerPushPin);
            bingMap.MapElements.Add(polylineDirection);
            ischangelanguage = false;
            Gps.PositionChanged += Gps_PositionChanged;
            Gps.StatusChanged += Gps_StatusChanged;
            Gps.OnTimeOut += Gps_OnTimeOut;
            HideWaiting();
            CheckInternet();
            LoadTheme();
            detailDialog.OnSaveFavorite += saveFavorite;
            detailDialog.OnSearchDirection += searchDirection;
            //bingMap.ZoomLevelChanged += bingMap_ZoomLevelChanged;
            (ApplicationBar as ApplicationBar).BackgroundColor = AppViewModel.Instance.SettingVM.BGColor_Appbar;
            toast.Visibility = System.Windows.Visibility.Collapsed;
            //startGps();
            //COMMAND = MainPage_Command.SEARCH_NEAR_BY;
            this.Loaded += MainPage_Loaded;
            tbSearch.Foreground = new SolidColorBrush(Colors.LightGray);
            if (AppViewModel.Instance.SettingVM.Language == "Vi")
                tbSearch.Text = LangVi.str_searchHintText;
            else
                tbSearch.Text = LangEn.str_searchHintText;

        }




        private void SetViewOnMap()
        {
            CurrentLocationPin currenPin = new CurrentLocationPin();
            MapOverlay overlay = new MapOverlay();
            overlay.GeoCoordinate = new GeoCoordinate(AppViewModel.Instance.SettingVM.UserLocationLattitude, AppViewModel.Instance.SettingVM.UserLocationLongitude);
            overlay.Content = currenPin;
            layerPushPin.Add(overlay);
            bingMap.SetView(new GeoCoordinate(AppViewModel.Instance.SettingVM.UserLocationLattitude, AppViewModel.Instance.SettingVM.UserLocationLongitude), Constant.MAP_ZOOM_LEVEL_DEFAULT, MapAnimationKind.Linear);
        }
        private void LoadTheme()
        {
            titleBG.Stroke = new SolidColorBrush(AppViewModel.Instance.SettingVM.BGColor_titBG);
            titleBG.Fill = new SolidColorBrush(AppViewModel.Instance.SettingVM.BGColor_titBG);

        }
        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            if (isfrist)
            {
                NavigationService.Navigate(new Uri("/View/Page/SearchPage.xaml", UriKind.Relative));
                isfrist = false;
            }
            else
                this.ApplicationBar.IsVisible = true;                
        }

        bool isGpsEnable = true;

        void Gps_OnTimeOut()
        {
            if (isGpsEnable == false)
            {
                if ((MainPage.Instance.ApplicationBar.Buttons[3] as ApplicationBarIconButton).IsEnabled == false)
                {
                    (MainPage.Instance.ApplicationBar.Buttons[3] as ApplicationBarIconButton).IsEnabled = true;
                }
                if (isGPSDisable == false)
                {
                    if (AppViewModel.Instance.SettingVM.Language == "Vi")
                    {
                        Toast(LangVi.errorGetGPS);
                    }
                    else
                    {
                        Toast(LangEn.errorGetGPS);
                    }
                }
            }
            else
            {
                isGpsEnable = true;
                return;
            }
            HideWaiting();
        }

        /// <summary>
        /// Invoke when user move to another location
        /// </summary>
        /// <param name="status"></param>
        void Gps_StatusChanged(GeoPositionStatus status)
        {
            switch (status)
            {
                case GeoPositionStatus.Disabled:
                    HideWaiting();
                    if (AppViewModel.Instance.SettingVM.Language == "Vi")
                        //MessageBox.Show(LangVi.errorGetGPS, "", MessageBoxButton.OK);
                        Toast(LangVi.errorGetGPS);
                    else
                    {
                        //MessageBox.Show(LangEn.errorGetGPS, "", MessageBoxButton.OK);
                        Toast(LangEn.errorGetGPS);
                    }
                    isGpsEnable = false;
                    isGPSDisable = true;
                    return;
                case GeoPositionStatus.Initializing:
                    //
                    break;
                case GeoPositionStatus.NoData:
                    isGPSDisable = false;
                    if (AppViewModel.Instance.SettingVM.Language == "Vi")
                        MainPage.Instance.Toast(LangVi.errorGetGPS);
                    else
                        MainPage.Instance.Toast(LangEn.errorGetGPS);
                    break;
                case GeoPositionStatus.Ready:
                //Date: 1/2/2013 TrungNguyen comment these lines to fix bug
                //if (AppViewModel.Instance.SettingVM.Language == "Vi")
                //    MainPage.Instance.Toast(LangVi.GetGPS);
                //else
                //    MainPage.Instance.Toast(LangEn.GetGPS);
                //break;
                default:
                    break;
            }
        }

        /// <summary>
        /// Change language
        /// </summary>
        /// <param name="languageName"></param>
        private void ReloadLanguage(string languageName)
        {

            switch (languageName)
            {
                case "Vi":
                    (ApplicationBar.MenuItems[0] as ApplicationBarMenuItem).Text = LangVi.strPolicyHeading;
                    (ApplicationBar.MenuItems[1] as ApplicationBarMenuItem).Text = LangVi.str_Feedback;
                    (ApplicationBar.Buttons[0] as ApplicationBarIconButton).Text = LangVi.str_setting;
                    (ApplicationBar.Buttons[1] as ApplicationBarIconButton).Text = LangVi.str_favorites;
                    (ApplicationBar.Buttons[2] as ApplicationBarIconButton).Text = LangVi.str_history;
                    (ApplicationBar.Buttons[3] as ApplicationBarIconButton).Text = LangVi.str_search;

                    break;
                case "En":
                    (ApplicationBar.MenuItems[0] as ApplicationBarMenuItem).Text = LangEn.strPolicyHeading;
                    (ApplicationBar.MenuItems[1] as ApplicationBarMenuItem).Text = LangEn.str_Feedback;
                    (ApplicationBar.Buttons[0] as ApplicationBarIconButton).Text = LangEn.str_setting;
                    (ApplicationBar.Buttons[1] as ApplicationBarIconButton).Text = LangEn.str_favorites;
                    (ApplicationBar.Buttons[2] as ApplicationBarIconButton).Text = LangEn.str_history;
                    (ApplicationBar.Buttons[3] as ApplicationBarIconButton).Text = LangEn.str_search;
                    break;
            }

            if (LanguageChange == languageName)
            {
                // do nothing
            }
            else
            {
                ischangelanguage = true;
                LanguageChange = languageName;

            }
        }
        void bingMap_ZoomLevelChanged(object sender, MapZoomLevelChangedEventArgs e)
        {
            bool isNear = bingMap.ZoomLevel > 1 ? true : false;

            foreach (var overlay in layerPushPin)
            {
                if (overlay.Content is YellowMapPin)
                {
                    if (isNear)
                    {
                        (overlay.Content as YellowMapPin).ShowFull();
                    }
                    else
                        (overlay.Content as YellowMapPin).ShowIcon();
                }
            }
        }

        public void ShowWaiting()
        {
            isWaitingShow = true;
            border_progressBar.Visibility = System.Windows.Visibility.Visible;
        }

        public void HideWaiting()
        {
            isWaitingShow = false;
            border_progressBar.Visibility = System.Windows.Visibility.Collapsed;
        }

        GeoCoordinate SearchFromLocation = null;
        GeoCoordinate SearchToLocation = null;
        void searchDirection(string from, string to)
        {
            Launch();
            //ShowWaiting();
            //SearchFromLocation = null;
            //SearchToLocation = null;
            //COMMAND = MainPage_Command.GET_DIRECTION;
            //if (from == "")
            //{
            //    startGps();
            //    //HideWaiting();
            //}
            //else
            //{
            //    GoogleServiceHandler service = new GoogleServiceHandler();
            //    service.OnGetGeocodingLocation += OnRecieveFromLocation;
            //    service.GetLocationByAddress(from);
            //    //HideWaiting();
            //}

            //if (to == "")
            //{
            //    SearchToLocation = new GeoCoordinate(detailDialog.Place.Lattitude, detailDialog.Place.Longitude);
            //    //HideWaiting();
            //}
            //else
            //{
            //    GoogleServiceHandler service = new GoogleServiceHandler();
            //    service.OnGetGeocodingLocation += OnRecieveToLocation;
            //    service.GetLocationByAddress(to);
            //    //HideWaiting();
            //}


        }

        private void Launch()
        {

            //MapsDirectionsTask mapsDirectionsTask = new MapsDirectionsTask();
            //LabeledMapLocation spaceNeedleLML = new LabeledMapLocation(detailDialog.Place.Name, new GeoCoordinate(detailDialog.Place.Lattitude, detailDialog.Place.Longitude));
            //mapsDirectionsTask.End = spaceNeedleLML;
            //mapsDirectionsTask.Show();

            BingMapsDirectionsTask task = new BingMapsDirectionsTask();
            task.Start = new LabeledMapLocation("My current location", new GeoCoordinate(AppViewModel.Instance.SettingVM.UserLocationLattitude, AppViewModel.Instance.SettingVM.UserLocationLongitude));
            task.End = new LabeledMapLocation(detailDialog.Place.Name, new GeoCoordinate(detailDialog.Place.Lattitude, detailDialog.Place.Longitude));
            task.Show();

            //string lat = detailDialog.Place.Lattitude.ToString();
            //string log = detailDialog.Place.Longitude.ToString();
            //string name = detailDialog.Place.Name;
            ////Uri uri = new Uri("ms-drive-to:?&destination.latitude=" + lat + "&destination.longtitude=" + log + "&destination.name=" + name);
            //string a = "explore-maps://v1.0/?latlon=" + lat + "," + log + "&zoom=15";
            //await Windows.System.Launcher.LaunchUriAsync(new Uri(a));
        }


        void OnRecieveToLocation(int n, double lat, double lng)
        {
            if (n == 0)
            {
                COMMAND = MainPage_Command.NONE;
                if (AppViewModel.Instance.SettingVM.Language == "Vi")
                {
                    Toast(LangVi.str_notfounddirection);
                }
                else
                {
                    Toast(LangEn.str_notfounddirection);
                }
                (ApplicationBar.Buttons[3] as ApplicationBarIconButton).IsEnabled = true;
                HideWaiting();
                return;
            }
            else
            {
                SearchToLocation = new GeoCoordinate(lat, lng);
                SearchDirectionAfterGet2Location();
            }
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            detailDialog.Hide();
            base.OnNavigatedFrom(e);
        }

        public void Toast(string note)
        {
            toast.Show(note);
        }

        void OnRecieveFromLocation(int n, double lat, double lng)
        {
            if (n == 0)
            {
                COMMAND = MainPage_Command.NONE;
                if (AppViewModel.Instance.SettingVM.Language == "Vi")
                {
                    Toast(LangVi.str_notfounddirection);
                }
                else
                {
                    Toast(LangEn.str_notfounddirection);
                }
                (ApplicationBar.Buttons[3] as ApplicationBarIconButton).IsEnabled = true;
                HideWaiting();
                return;
            }
            else
            {
                SearchFromLocation = new GeoCoordinate(lat, lng);
                SearchDirectionAfterGet2Location();
            }
        }

        void SearchDirectionAfterGet2Location()
        {
            if (COMMAND != MainPage_Command.GET_DIRECTION)
            {
                HideWaiting();
                SearchFromLocation = null;
                SearchToLocation = null;
                return;
            }

            if (SearchToLocation == null || SearchFromLocation == null)
            {
                // Wait until get 2 location
                return;
            }

            //
            GoogleServiceHandler service = new GoogleServiceHandler();
            service.GetDirection(SearchFromLocation.Latitude, SearchFromLocation.Longitude,
                SearchToLocation.Latitude, SearchToLocation.Longitude);
            service.OnGetDirection += service_OnGetDirection;


            COMMAND = MainPage_Command.NONE;
        }

        void service_OnGetDirection(GoogleDirectionResponse response)
        {
            if (response.Status.ToUpper() != "OK")
            {
                if (AppViewModel.Instance.SettingVM.Language == "Vi")
                {
                    Toast(LangVi.str_notfounddirection);
                }
                else
                {
                    Toast(LangEn.str_notfounddirection);
                }
                (ApplicationBar.Buttons[3] as ApplicationBarIconButton).IsEnabled = true;
                HideWaiting();
                return;
            }




            DirectionResponse = response;
            //NavigationService.Navigate(new Uri("/View/Page/DirectionMapPage.xaml", UriKind.Relative));
            directionMap = new DirectionMap();
            if (directionMap.IsOutOfMemory == false)
            {
                gridDirectionMap.Children.Add(directionMap);
                HideWaiting();
            }
            else
            {
                directionMap = null;
                if (AppViewModel.Instance.SettingVM.Language == "Vi")
                {
                    Toast(LangVi.str_errorSearchDirection);
                }
                else
                {
                    Toast(LangEn.str_errorSearchDirection);
                }
                HideWaiting();
                (ApplicationBar.Buttons[3] as ApplicationBarIconButton).IsEnabled = true;

            }

            //directionMap.ShowDirectionMap();
        }




        #region Save Favorite
        async void saveFavorite()
        {
            Favorite f = new Favorite();
            f.Address = detailDialog.Detail.Address;
            f.Latitude = selectedPlace.Lattitude;
            f.Longitude = selectedPlace.Longitude;
            f.Name = detailDialog.Detail.Name;
            f.PlaceId = detailDialog.Detail.Id;
            f.SubCate = selectedPlace.SubCate;

            bool result = await DBHelper.InsertFavorite(f);

            if (AppViewModel.Instance.SettingVM.Language == "Vi")
                Toast(LangVi.str_addFavorites);
            else
                Toast(LangEn.str_addFavorites);
        }
        #endregion


        public void LoadState()
        {
            ChangeMapType(AppViewModel.Instance.SettingVM.MapType);
        }

        bool isInternetConnection = true;
        DispatcherTimer timerInternetTimeOut = new DispatcherTimer();
        public void CheckInternet()
        {
            //typeConnection();
            //if (Microsoft.Phone.Net.NetworkInformation.NetworkInterface.NetworkInterfaceType == Microsoft.Phone.Net.NetworkInformation.NetworkInterfaceType.None)
            //{
            //    if (AppViewModel.Instance.SettingVM.Language == "Vi")
            //    {
            //        //MessageBox.Show(LangVi.str_noNetwork, "", MessageBoxButton.OK);
            //        Toast(LangVi.str_noNetwork);
            //    }
            //    else
            //    {
            //        //MessageBox.Show(LangEn.str_noNetwork, "", MessageBoxButton.OK);
            //        Toast(LangEn.str_noNetwork);
            //    }
            //    (ApplicationBar.Buttons[3] as ApplicationBarIconButton).IsEnabled = true;
            //    HideWaiting();
            //    IsWifiDisabble = true;
            //    return;
            //}
            //IsWifiDisabble = false;
            //isInternetConnection = false;
            timerInternetTimeOut.Interval = new TimeSpan(0, 0, 2);
            timerInternetTimeOut.Stop();
            WebClient checkInternet = new WebClient();
            checkInternet.OpenReadAsync(new Uri("https://www.google.com.vn/"));
            checkInternet.OpenReadCompleted += checkInternet_OpenReadCompleted;
            timerInternetTimeOut.Start();

        }


        void timerInternetTimeOut_Tick(object sender, EventArgs e)
        {
            timerInternetTimeOut.Stop();
            if (isInternetConnection)
            {
                return;
            }

            isInternetConnection = true;
            if (AppViewModel.Instance.SettingVM.Language == "Vi")
            {
                Toast(LangVi.str_noInternet);
            }
            else
            {
                Toast(LangEn.str_noInternet);
            }
            (ApplicationBar.Buttons[3] as ApplicationBarIconButton).IsEnabled = true;
            HideWaiting();
        }

        void checkInternet_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            if (isInternetConnection)
            {
                return;
            }

            isInternetConnection = true;
            #region Detect connection
            bool isConnect = false;

            try
            {
                if (e.Result == null)
                {
                    Debug.WriteLine("Khong co internet");
                }
                else
                {
                    isConnect = true;
                    Debug.WriteLine("Co internet");
                }
            }
            catch (Exception)
            {
                isConnect = false;
            }
            #endregion

            ConnectionStatusChanged(isConnect);
        }

        void ConnectionStatusChanged(bool status)
        {
            if (status == false)
            {
                if (AppViewModel.Instance.SettingVM.Language == "Vi")
                {
                    Toast(LangVi.str_noInternet);
                }
                else
                {
                    Toast(LangEn.str_noInternet);
                }
            }
        }

        void Gps_PositionChanged(System.Device.Location.GeoCoordinate loc)
        {
            Gps.Stop();
            AppViewModel.Instance.SettingVM.UserLocationLattitude = loc.Latitude;
            AppViewModel.Instance.SettingVM.UserLocationLongitude = loc.Longitude;

            if (COMMAND == MainPage_Command.GET_DIRECTION)
            {
                ShowWaiting();
                SearchFromLocation = loc;
                SearchDirectionAfterGet2Location();
                return;
            }

            //bingMap.SetView(loc, bingMap.ZoomLevel, MapAnimationKind.Linear);
            HideWaiting();



            if (COMMAND == MainPage_Command.SEARCH_NEAR_BY)
            {
                GoogleServiceHandler service = new GoogleServiceHandler();
                service.OnGetPlace += showNearByLocation;
                service.GetPlace();
            }

            CallSearchDirectly();

            COMMAND = MainPage_Command.NONE;
        }

        void showNearByLocation(List<Place> places)
        {
            ShowPlace(places);
        }

        /// <summary>
        /// Start getting current location
        /// </summary>
        void startGps()
        {
            if (AppViewModel.Instance.SettingVM.GPS == 0)
            {
                if (AppViewModel.Instance.SettingVM.Language == "Vi")
                {
                    Toast(LangVi.str_OffGpsMeg);
                }
                else
                {
                    Toast(LangEn.str_OffGpsMeg);
                }
                HideWaiting();
                return;
            }

            else
            {
                ShowWaiting();
                isGpsEnable = true;
                Gps.Start();
            }
        }

        /// <summary>
        /// Get current center location on map
        /// </summary>
        public GeoCoordinate CenterLocation
        {
            get
            {
                return bingMap.Center;
            }
        }

        /// <summary>
        ///  Call this  method to apply new map type
        /// </summary>
        /// <param name="type"></param>
        public void ChangeMapType(int type)
        {
            switch (type)
            {
                case 0:
                    bingMap.CartographicMode = MapCartographicMode.Road;
                    break;
                case 1:
                    bingMap.CartographicMode = MapCartographicMode.Aerial;
                    break;
                case 2:
                    bingMap.CartographicMode = MapCartographicMode.Hybrid;
                    break;
                case 3:
                    bingMap.CartographicMode = MapCartographicMode.Terrain;
                    break;
                default:
                    break;
            }
        }


        /// <summary>
        /// Call this method to show venue (int favorite od history) on map
        /// </summary>
        void CallShowDirectly()
        {
            if (COMMAND == MainPage_Command.SHOW_FAVORITE)
            {
                bingMap.ZoomLevel = Constant.MAP_ZOOM_LEVEL;
                Favorite f = AppViewModel.Instance.SettingVM.SelectedFavorite;
                Place p = new Place();
                p.Address = f.Address;
                p.Lattitude = f.Latitude;
                p.Longitude = f.Longitude;
                p.Name = f.Name;
                p.PlaceId = f.PlaceId;
                p.SubCate = f.SubCate;
                
                List<Place> lstPlace = new List<Place>();
                lstPlace.Add(p);
                ShowPlace(lstPlace);

            }

            if (COMMAND == MainPage_Command.SHOW_HISTORY)
            {
                bingMap.ZoomLevel = Constant.MAP_ZOOM_LEVEL;
                History f = AppViewModel.Instance.SettingVM.SelectedHistory;
                Place p = new Place();
                p.Address = f.Address;
                p.Lattitude = f.Latitude;
                p.Longitude = f.Longitude;
                p.Name = f.Name;
                p.PlaceId = f.PlaceId;
                p.SubCate = f.SubCate;

                List<Place> lstPlace = new List<Place>();
                lstPlace.Add(p);
                ShowPlace(lstPlace);

            }
        }

        /// <summary>
        /// Call this method after get start point and end point to search place
        /// </summary>
        public static bool isSearchByCate = false;

        public void CallSearchDirectly()
        {
           

            if (COMMAND == MainPage_Command.SEARCH_FAVORITE)
            {
                int searchFrom = AppViewModel.Instance.SettingVM.SearchFrom;
                if (searchFrom == Constant.SEARCHFROM_CURRENT)
                {
                    bingMap.SetView(new GeoCoordinate(AppViewModel.Instance.SettingVM.UserLocationLattitude, AppViewModel.Instance.SettingVM.UserLocationLongitude), Constant.MAP_ZOOM_LEVEL_DEFAULT, MapAnimationKind.Linear);
                }
                //bingMap.ZoomLevel = Constant.MAP_ZOOM_LEVEL;
                GoogleServiceHandler service = new GoogleServiceHandler();
                service.OnGetPlace += showNearByLocation;
                service.GetPlaceByKeyWord(AppViewModel.Instance.SettingVM.SelectedFavorite.Name);
                //service.GetPlace(SelectedFavorite);
                isSearchByCate = false;
            }

            if (COMMAND == MainPage_Command.SEARCH_HISTORY)
            {
                int searchFrom = AppViewModel.Instance.SettingVM.SearchFrom;
                if (searchFrom == Constant.SEARCHFROM_CURRENT)
                {
                    bingMap.SetView(new GeoCoordinate(AppViewModel.Instance.SettingVM.UserLocationLattitude, AppViewModel.Instance.SettingVM.UserLocationLongitude), Constant.MAP_ZOOM_LEVEL_DEFAULT, MapAnimationKind.Linear);
                }
                //bingMap.ZoomLevel = Constant.MAP_ZOOM_LEVEL;
                GoogleServiceHandler service = new GoogleServiceHandler();
                service.OnGetPlace += showNearByLocation;
                service.GetPlaceByKeyWord(AppViewModel.Instance.SettingVM.SelectedHistory.Name);
                //service.GetPlace(SelectedHistory);
                isSearchByCate = false;
            }

            if (COMMAND == MainPage_Command.SEARCH_NORMAL)
            {
                //bingMap.ZoomLevel = Constant.MAP_ZOOM_LEVEL;
                GoogleServiceHandler service = new GoogleServiceHandler();
                service.GetPlace();
                service.OnGetPlace += showNearByLocation;
                isSearchByCate = true;

            }
            if (COMMAND == MainPage_Command.SEARCH_BYKEYWORD)
            {
                //bingMap.ZoomLevel = Constant.MAP_ZOOM_LEVEL;
                GoogleServiceHandler service = new GoogleServiceHandler();
                service.OnGetPlace += showNearByLocation;
                service.GetPlaceByKeyWord(SearchKeyword);
                isSearchByCate = false;
            }
        }

        /// <summary>
        /// this method will be invoke when navigate from anothe page, depend on MainPage_Command, it will do different action
        /// </summary>
        /// <param name="e"></param>
        public static bool IsWifiDisabble = false;
        protected override async void OnNavigatedTo(NavigationEventArgs e)
        {

            //[pkhuy]: log
#if DEBUG
            string strLog = "OnNavigatedTo";
#endif

#if DEBUG
                strLog += "~1. " +
                        "AppViewModel.Instance.SettingVM.UserLocationLattitude=" + AppViewModel.Instance.SettingVM.UserLocationLattitude + "~" +
                        "AppViewModel.Instance.SettingVM.UserLocationLongitude=" + AppViewModel.Instance.SettingVM.UserLocationLongitude + "~" +
                        "AppViewModel.Instance.SettingVM.SearchFrom=" + AppViewModel.Instance.SettingVM.SearchFrom + "~" +
                        "AppViewModel.Instance.SettingVM.MapLattitude=" + AppViewModel.Instance.SettingVM.MapLattitude + "~" +
                        "AppViewModel.Instance.SettingVM.MapLongitude=" + AppViewModel.Instance.SettingVM.MapLongitude;
#endif

            if (AppViewModel.Instance.SettingVM.UserLocationLattitude == 0 && AppViewModel.Instance.SettingVM.UserLocationLongitude == 0 && AppViewModel.Instance.SettingVM.SearchFrom == 0)
            {
#if DEBUG
                strLog += "~2. ";
#endif
                if (AppViewModel.Instance.SettingVM.MapLattitude != 0 && AppViewModel.Instance.SettingVM.MapLongitude != 0)
                {
#if DEBUG
                    strLog += "~3. ";
#endif
                    bingMap.SetView(new GeoCoordinate(AppViewModel.Instance.SettingVM.MapLattitude, AppViewModel.Instance.SettingVM.MapLongitude), Constant.MAP_ZOOM_LEVEL_DEFAULT, MapAnimationKind.None);
                }
                else
                {
#if DEBUG
                    strLog += "~4. ";
#endif
                    bingMap.SetView(new GeoCoordinate(AppViewModel.Instance.SettingVM.UserLocationLattitude, AppViewModel.Instance.SettingVM.UserLocationLongitude), 2, MapAnimationKind.None);
                }
            }
            else if (AppViewModel.Instance.SettingVM.SearchFrom == 0)
            {
#if DEBUG
                strLog += "~5. ";
#endif
                if (isfrist == true && AppViewModel.Instance.SettingVM.UserLocationLattitude != 0 && AppViewModel.Instance.SettingVM.UserLocationLongitude != 0)
                {
#if DEBUG
                    strLog += "~6. ";
#endif
                    SetViewOnMap();
                }
                //SetViewOnMap();
            }
            else if (AppViewModel.Instance.SettingVM.SearchFrom == 1)
            {
                //if (AppViewModel.Instance.SettingVM.MapLattitude == 0 && AppViewModel.Instance.SettingVM.MapLongitude == 0)
                //{
                //    bingMap.SetView(new GeoCoordinate(MainPage.Instance.CenterLocation.Latitude, MainPage.Instance.CenterLocation.Longitude), 15, MapAnimationKind.Linear);
                //}
                //else
                //{
                //    bingMap.SetView(new GeoCoordinate(AppViewModel.Instance.SettingVM.MapLattitude, AppViewModel.Instance.SettingVM.MapLongitude), 15, MapAnimationKind.Linear);

                //}

                if (AppViewModel.Instance.SettingVM.MapLattitude == 0 && AppViewModel.Instance.SettingVM.MapLongitude == 0)
                {
#if DEBUG
                    strLog += "~7. ";
#endif
                    bingMap.SetView(new GeoCoordinate(32.892613, -117.194174), Constant.MAP_ZOOM_LEVEL_DEFAULT, MapAnimationKind.None);
                    AppViewModel.Instance.SettingVM.MapLattitude = 32.892613;
                    AppViewModel.Instance.SettingVM.MapLongitude = -117.194174;
                }
                else
                {
#if DEBUG
                    strLog += "~8. ";
#endif
                        if (bingMap.ZoomLevel < 10)
                        {
#if DEBUG
                            strLog += "~9. ";
#endif
                            bingMap.SetView(new GeoCoordinate(AppViewModel.Instance.SettingVM.MapLattitude, AppViewModel.Instance.SettingVM.MapLongitude), Constant.MAP_ZOOM_LEVEL_DEFAULT, MapAnimationKind.None);
                        }
                        else
                        {
#if DEBUG
                            strLog += "~10. ";
#endif
                            bingMap.SetView(new GeoCoordinate(AppViewModel.Instance.SettingVM.MapLattitude, AppViewModel.Instance.SettingVM.MapLongitude), bingMap.ZoomLevel, MapAnimationKind.None);
                        }

                }
            }

            //[pkhuy]: log
#if DEBUG
            await Logger.WriteLog(strLog);
#endif

            ReloadLanguage(AppViewModel.Instance.SettingVM.Language);
            ChangeMapType(AppViewModel.Instance.SettingVM.MapType);
            
            if (IsWifiDisabble)
            {
                HideWaiting();
                return;
            }
            else
            {
                // showSetting();
                if (directionMap != null)
                {
                    if (ischangelanguage == true)
                    {
                        directionMap.Close();

                    }
                    directionMap.ChangeMapType(AppViewModel.Instance.SettingVM.MapType);
                }

                if (COMMAND != MainPage_Command.NONE)
                {
                    if (gridDirectionMap.Children.Count > 0)
                    {
                        directionMap.Close();
                        directionMap = null;
                    }
                }

                base.OnNavigatedTo(e);

                if (COMMAND == MainPage_Command.MOVE_MAP)
                {
                    if (move_map_lng != 0 && move_map_lat != 0)
                    {
                        bingMap.SetView(new GeoCoordinate(move_map_lat, move_map_lng), Constant.MAP_ZOOM_LEVEL_DEFAULT, MapAnimationKind.Linear);
                    }
                    COMMAND = MainPage_Command.NONE;
                }

                if (COMMAND == MainPage_Command.SEARCH_FAVORITE
                    || COMMAND == MainPage_Command.SEARCH_HISTORY
                    || COMMAND == MainPage_Command.SEARCH_BYKEYWORD
                    || COMMAND == MainPage_Command.SEARCH_NORMAL)
                {
                    int searchFrom = AppViewModel.Instance.SettingVM.SearchFrom;


                    if (searchFrom == Constant.SEARCHFROM_CURRENT)
                    {
                        //get GPS first
                        startGps();
                        return;
                    }
                    else
                    {
                        //if (SearchPage.isSetting)
                        //{
                        //    bingMap.SetView(new GeoCoordinate(32.892613, -117.194174), Constant.MAP_ZOOM_LEVEL_DEFAULT, MapAnimationKind.Linear);
                        //    AppViewModel.Instance.SettingVM.MapLattitude = 32.892613;
                        //    AppViewModel.Instance.SettingVM.MapLongitude = -117.194174;
                        //    Task.Delay(1000);
                        //    CallSearchDirectly();
                        //}
                        //else
                        {
                            Task.Delay(1000);
                            CallSearchDirectly();
                        }
                    }

                }

                if (COMMAND == MainPage_Command.SHOW_FAVORITE || COMMAND == MainPage_Command.SHOW_HISTORY)
                {
                    CallShowDirectly();
                }

                if (COMMAND != MainPage_Command.SEARCH_NEAR_BY)
                    COMMAND = MainPage_Command.NONE;


                ischangelanguage = false;
            }
        }


        /// <summary>
        /// Call back event after geting place
        /// </summary>
        /// <param name="places"></param>
        void service_OnGetPlace(List<Place> places)
        {
            ShowPlace(places);
        }

        /// <summary>
        /// Call back event click button MyLocation, it will start getting current location
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnMyLocation_Click(object sender, System.EventArgs e)
        {
            startGps();
        }

        /// <summary>
        /// Clear all push pin on map, it will be call every time add list venue on map
        /// </summary>
        public void ClearPushPin()
        {
            layerPushPin.Clear();
        }

        /// <summary>
        /// Add single push pin on map
        /// </summary>
        /// <param name="pin"></param>
        public void AddPushPin(YellowMapPin pin)
        {
            pin.OnShowDetail += pin_OnShowDetail;
            MapOverlay overlay = new MapOverlay();
            overlay.GeoCoordinate = new GeoCoordinate(pin.Place.Lattitude, pin.Place.Longitude);
            overlay.Content = pin;
            pin.MapOverlay = overlay;
            layerPushPin.Add(overlay);
        }

        public MapLayer LayerPushPin
        {
            get
            {
                return layerPushPin;
            }
        }

        Place selectedPlace;

        /// <summary>
        /// call back function after tap on push pin
        /// </summary>
        /// <param name="p"></param>
        void pin_OnShowDetail(Place p)
        {
            if (isWaitingShow)
                return;
            else
            {
                var point = bingMap.ConvertGeoCoordinateToViewportPoint(new GeoCoordinate(p.Lattitude, p.Longitude));
                point.Y += 40;
                point.X += 40;
                var latlng = bingMap.ConvertViewportPointToGeoCoordinate(point);

                bingMap.SetView(latlng, bingMap.ZoomLevel, MapAnimationKind.Linear);

                GoogleServiceHandler service = new GoogleServiceHandler();
                service.OnGetDetail += service_OnGetDetail;
                service.GetDetail(p);
                selectedPlace = p;
            }
        }

        /// <summary>
        /// Call back function after get place detail from google service, it will show detail dialog on map, current venue is moved to center
        /// </summary>
        /// <param name="p"></param>
        void service_OnGetDetail(Detail p)
        {
            if (p == null)
            {
                if (AppViewModel.Instance.SettingVM.Language == "Vi")
                {
                    Toast(LangVi.str_notgetdetail);
                }
                else
                {
                    Toast(LangEn.str_notgetdetail);
                }
                return;
            }
            detailDialog.Place = selectedPlace;
            detailDialog.Show(p);
            History history = new History();
            history.PlaceId = p.Id;
            history.Name = p.Name;
            history.Address = p.Address;
            history.SubCate = selectedPlace.SubCate;
            history.Time = DateTime.Now.Ticks;
            history.Latitude = selectedPlace.Lattitude;
            history.Longitude = selectedPlace.Longitude;

            DBHelper.InsertHistory(history);
        }

        /// <summary>
        /// Show list venue on map, before adding, it will clear all last venues
        /// </summary>
        /// <param name="places"></param>
        public void ShowPlace(List<Place> places)
        {

            ClearPushPin();


            if (places.Count == 0)
            {
                if (AppViewModel.Instance.SettingVM.Language == "Vi")
                {
                    Toast(LangVi.str_nolocation);
                }
                else
                {
                    Toast(LangEn.str_nolocation);
                }
                HideWaiting();
                //SetViewOnMap();
                return;

            }

            string color = "";

            double minLat, minLng, maxLat, maxLng;
            minLat = 500;
            minLng = 500;
            maxLat = -500;
            maxLng = -500;
            #region calculate View
            foreach (var place in places)
            {

                if (place.Lattitude < minLat)
                    minLat = place.Lattitude;

                if (place.Lattitude > maxLat)
                    maxLat = place.Lattitude;

                if (place.Longitude < minLng)
                    minLng = place.Longitude;

                if (place.Longitude > maxLng)
                    maxLng = place.Longitude;

            }
            #endregion

            GeoCoordinate center = new GeoCoordinate((maxLat + minLat) / 2, (maxLng + minLng) / 2);


            CurrentLocationPin currenPin = new CurrentLocationPin();

            MapOverlay overlay = new MapOverlay();
            overlay.GeoCoordinate = new GeoCoordinate(AppViewModel.Instance.SettingVM.UserLocationLattitude, AppViewModel.Instance.SettingVM.UserLocationLongitude);
            overlay.Content = currenPin;
            layerPushPin.Add(overlay);


            #region Add YallowMapPin
            foreach (var place in places)
            {
                string placeSubCateId = place.SubCate;
                foreach (var cate in AppViewModel.Instance.Categories)
                {
                    if (placeSubCateId.Contains(cate.Id))
                    {
                        color = cate.Color;
                    }
                }

                YellowMapPin pin = new YellowMapPin();
                pin.Init(place, "#0176FA");
                AddPushPin(pin);
            }
            #endregion

            //bingMap.SetView(new LocationRectangle(center, maxLat - minLat, maxLng - minLng));


            if (places.Count == 1)
            {
                bingMap.SetView(center, bingMap.ZoomLevel, MapAnimationKind.Linear);

            }
            else
            {
                bingMap.SetView(new LocationRectangle(center, maxLat - minLat, maxLng - minLng), MapAnimationKind.Parabolic);
            }

            //center.Latitude = AppViewModel.Instance.SettingVM.UserLocationLattitude;
            //center.Longitude = AppViewModel.Instance.SettingVM.UserLocationLongitude;
            //bingMap.SetView(center, Constant.MAP_ZOOM_LEVEL_DEFAULT);
            bingMap.UpdateLayout();


            HideWaiting();
        }





        public void ShowNextPlace(List<Place> places)
        {
            string color = "";
            #region Add YallowMapPin
            foreach (var place in places)
            {
                string placeSubCateId = place.SubCate;
                foreach (var cate in AppViewModel.Instance.Categories)
                {
                    if (placeSubCateId.Contains(cate.Id))
                    {
                        color = cate.Color;
                    }
                }

                YellowMapPin pin = new YellowMapPin();
                pin.Init(place, "#7F0176FA");
                AddPushPin(pin);
            }

            HideWaiting();
            #endregion

        }






        /// <summary>
        /// call back function after click button Search on Detail dialog
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// 

        private void btnSearch_Click(object sender, EventArgs e)
        {
            if (isWaitingShow)
                return;
            else
            {
                if (detailDialog.IsShow == true)
                {
                    detailDialog.Hide();
                }
                if (tbSearch.Visibility == System.Windows.Visibility.Collapsed)
                {
                    titleBG.Visibility = System.Windows.Visibility.Visible;
                    tbSearch.Visibility = System.Windows.Visibility.Visible;
                    imagesearch.Visibility = System.Windows.Visibility.Visible;
                    tbSearch.Focus();
                }
                else
                {
                    titleBG.Visibility = System.Windows.Visibility.Collapsed;
                    tbSearch.Visibility = System.Windows.Visibility.Collapsed;
                    imagesearch.Visibility = System.Windows.Visibility.Collapsed;
                }
            }
        }

        /// <summary>
        /// Call back function when user tap on Favorite button in menu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnFavorite_Click(object sender, EventArgs e)
        {
            if (tbSearch.Visibility == System.Windows.Visibility.Visible)
            {
                imagesearch.Visibility = System.Windows.Visibility.Collapsed;
                titleBG.Visibility = System.Windows.Visibility.Collapsed;
                tbSearch.Visibility = System.Windows.Visibility.Collapsed;
            }
            if (isWaitingShow)
                return;
            else
                NavigationService.Navigate(new Uri("/View/Page/FavoritesPage.xaml", UriKind.Relative));
        }

        /// <summary>
        /// Call back function when user tap on History button in menu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnHistory_Click(object sender, EventArgs e)
        {
            if (tbSearch.Visibility == System.Windows.Visibility.Visible)
            {
                imagesearch.Visibility = System.Windows.Visibility.Collapsed;
                titleBG.Visibility = System.Windows.Visibility.Collapsed;
                tbSearch.Visibility = System.Windows.Visibility.Collapsed;
            }
            if (isWaitingShow)
                return;
            else
                NavigationService.Navigate(new Uri("/View/Page/HistoryPage.xaml", UriKind.Relative));
        }

        /// <summary>
        /// Call back function when user tap on setting button in menu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSetting_Click(object sender, EventArgs e)
        {
            if (tbSearch.Visibility == System.Windows.Visibility.Visible)
            {
                imagesearch.Visibility = System.Windows.Visibility.Collapsed;
                titleBG.Visibility = System.Windows.Visibility.Collapsed;
                tbSearch.Visibility = System.Windows.Visibility.Collapsed;
            }
            if (isWaitingShow)
                return;
            else
                NavigationService.Navigate(new Uri("/View/Page/SettingPage.xaml", UriKind.Relative));
        }

        Point centerPointOfMap = new Point();
        /// <summary>
        /// Call back event when Map is zoomed in or zoomed out, if it's zoomed so near, push pin will show label
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bingMap_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
        {
            // TODO: Add event handler implementation here.
            centerPointOfMap.X = e.NewSize.Width / 2;
            centerPointOfMap.Y = e.NewSize.Height / 2 - 150;
        }

        void showSetting()
        {
            Toast(Setting.Get("Language").ToString());
        }

        protected override async void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
#if DEBUG
            string strLog = "OnBackKeyPress";
            strLog += "~" + "MainPage.Instance.CenterLocation.Latitude=" + MainPage.Instance.CenterLocation.Latitude + "~"
                + "MainPage.Instance.CenterLocation.Longitude=" + MainPage.Instance.CenterLocation.Longitude + "~"
                + "MainPage.Instance.SettingVM.MapLattitude=" + AppViewModel.Instance.SettingVM.MapLattitude + "~"
                + "MainPage.Instance.SettingVM.MapLongitude=" + AppViewModel.Instance.SettingVM.MapLongitude + "~";
#endif                

            AppViewModel.Instance.SettingVM.MapLattitude = MainPage.Instance.CenterLocation.Latitude;
            AppViewModel.Instance.SettingVM.MapLongitude = MainPage.Instance.CenterLocation.Longitude;


            if (directionMap != null && directionMap.IsShowDList == true)
            {
                directionMap.IsShowDList = false;
                e.Cancel = true;               
            }
            else if (directionMap != null && directionMap.Visibility == System.Windows.Visibility.Visible)
            {
                if (gridDirectionMap.Children.Count > 0)
                {

                    directionMap.Close();
                    directionMap = null;
                }
                (MainPage.Instance.ApplicationBar.Buttons[3] as ApplicationBarIconButton).IsEnabled = true;
                if (tbSearch.Visibility == System.Windows.Visibility.Visible)
                {
                    titleBG.Visibility = System.Windows.Visibility.Collapsed;
                    tbSearch.Visibility = System.Windows.Visibility.Collapsed;
                    imagesearch.Visibility = System.Windows.Visibility.Collapsed;
                }
                e.Cancel = true;            
            }
            else if (detailDialog.IsShow)
            {
                detailDialog.Hide();
                e.Cancel = true;                
            }
            else
            {
                base.OnBackKeyPress(e);
                if ((ApplicationBar.Buttons[3] as ApplicationBarIconButton).IsEnabled == false)
                {
                    (ApplicationBar.Buttons[3] as ApplicationBarIconButton).IsEnabled = true;
                }
                NavigationService.Navigate(new Uri("/View/Page/SearchPage.xaml", UriKind.Relative));
            }

            //[pkhuy]: log
#if DEBUG
            strLog += "saved lat,long";
            await Logger.WriteLog(strLog);
#endif

        }

        public static bool isKeyDown = false;
        private void tbSearch_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            isKeyDown = true;
            if (e.Key == System.Windows.Input.Key.Enter)
            {
                tbSearch.Text = tbSearch.Text.Trim();

                if (tbSearch.Text.Contains(","))
                {
                    string[] strsLocation = tbSearch.Text.Split(new char[] { ',' });
                    float lat = 0;
                    float lng = 0;
                    if (strsLocation.Length == 2)
                    {
                        if (float.TryParse(strsLocation[0].Trim(), out lat) && float.TryParse(strsLocation[1].Trim(), out lng))
                        {
                            MainPage.move_map_lat = lat;
                            MainPage.move_map_lng = lng;
                            MainPage.COMMAND = MainPage_Command.MOVE_MAP;
                            return;
                        }
                    }

                }
                if (tbSearch.Text == LangVi.str_searchHintText || tbSearch.Text == LangEn.str_searchHintText)
                {
                    MainPage.SearchKeyword = "";
                }
                else if (tbSearch.Text == "")
                {
                    MainPage.SearchKeyword = "";
                }
                else
                {
                    MainPage.SearchKeyword = tbSearch.Text;
                }
                MainPage.COMMAND = MainPage_Command.SEARCH_BYKEYWORD;
                ShowWaiting();

                //[pkhuy]
                AppViewModel.Instance.SettingVM.MapLattitude = MainPage.Instance.CenterLocation.Latitude;
                AppViewModel.Instance.SettingVM.MapLongitude = MainPage.Instance.CenterLocation.Longitude;

                OnNavigatedTo(null);
                bingMap.Focus();
            }
        }
        private void tbSearch_LostFocus(object sender, RoutedEventArgs e)
        {
            if (isKeyDown == false)
            {
                tbSearch.Foreground = new SolidColorBrush(Colors.LightGray);
                if (AppViewModel.Instance.SettingVM.Language == "Vi")
                    tbSearch.Text = LangVi.str_searchHintText;
                else
                    tbSearch.Text = LangEn.str_searchHintText;
            }
            else if (isKeyDown == true && tbSearch.Text == "")
            {
                tbSearch.Foreground = new SolidColorBrush(Colors.LightGray);
                if (AppViewModel.Instance.SettingVM.Language == "Vi")
                    tbSearch.Text = LangVi.str_searchHintText;
                else
                    tbSearch.Text = LangEn.str_searchHintText;
            }
        }

        // handle when text box search got focus
        private void tbSearch_GotFocus(object sender, RoutedEventArgs e)
        {

            tbSearch.Foreground = new SolidColorBrush(Colors.Black);
            tbSearch.Text = "";
        }

        private void ApplicationBarMenuItem_Click_2(object sender, EventArgs e)
        {
            string site;
            if (AppViewModel.Instance.SettingVM.Language == "En")
            {
                site = "http://mobilesoft-tech.com/privacy_visualmapwin8e.html";
            }
            else
            {
                site = "http://mobilesoft-tech.com/privacy_visualmapwin8v.html";
            }
            WebBrowserTask a = new WebBrowserTask();
            a.Uri = new Uri(site, UriKind.Absolute);
            a.Show();
        }
        private void MenuFeedback_Click_1(object sender, EventArgs e)
        {
            var task = new EmailComposeTask { To = "support@mobilesoft-tech.com" };                      
            task.Show();
        }
    }
}